package cn.hiapi.shopkeeper.service.dashboard;

import cn.hiapi.basic.jpa.pageable.QueryWrapper;
import cn.hiapi.basic.token.enums.TokenType;
import cn.hiapi.finance.entity.Recharge;
import cn.hiapi.finance.enums.WithdrawStatus;
import cn.hiapi.finance.service.RechargeService;
import cn.hiapi.finance.service.WithdrawService;
import cn.hiapi.interfaces.DispatchContext;
import cn.hiapi.interfaces.system.IPlatformDashboardService;
import cn.hiapi.interfaces.system.data.DashboardItem;
import cn.hiapi.shop.service.shop.ShopService;
import cn.hiapi.shopkeeper.consts.AppConst;
import cn.hiapi.shopkeeper.enums.ActivityType;
import cn.hiapi.shopkeeper.service.activity.ActivityService;
import cn.hiapi.shopkeeper.service.order.ActivityGroupOrderService;
import cn.hiapi.shopkeeper.service.order.ActivityLotteryOrderService;
import cn.hiapi.shopkeeper.service.order.ActivityOrderService;
import cn.hiapi.user.service.UserService;
import cn.hiapi.utils.DateUtils;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;

/**
 * @author AdinZ
 * @date 2023/2/16 20:43
 */
@Service
public class AllDashboardService {

    private final DispatchContext dispatchContext;

    public AllDashboardService(DispatchContext dispatchContext) {
        this.dispatchContext = dispatchContext;
    }


    public Object sumTotalMoney(EntityManager em, String fidType, long startTime, long endTime) {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Object> query = cb.createQuery();
        Root<Recharge> root = query.from(Recharge.class);
        query.select(cb.sum(root.get("money"))).where(
                cb.equal(root.get("status"), 1),
                cb.equal(root.get("fidType"), fidType),
                cb.between(root.get("created"), startTime, endTime)
        );
        Object result = em.createQuery(query).getSingleResult();
        return result;
    }


    @Service
    public class ShopDashboardService implements IPlatformDashboardService {

        @Override
        public List<DashboardItem> dashboardData() {
            long totalCount = dispatchContext.getServiceOne(ShopService.class).count(new QueryWrapper().eq("type", 1).eq("status", 1));
            long waitReviewCount = dispatchContext.getServiceOne(ShopService.class).count(new QueryWrapper().eq("status", 0));
            return Lists.newArrayList(
                    DashboardItem.builder().label("店铺总数").value(totalCount).type(dashboardType()).build(),
                    DashboardItem.builder().label("待审核数").value(waitReviewCount).type(dashboardType()).build()
            );
        }


        @Override
        public String dashboardType() {
            return "shop";
        }
    }

    @Service
    public class OrderDashboardService implements IPlatformDashboardService {

        @Override
        public List<DashboardItem> dashboardData() {
            long totalCount = dispatchContext.getServiceOne(ActivityOrderService.class).count(
                    new QueryWrapper().eq("orderType", 1).between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime())
            );
            long waitReviewCount = dispatchContext.getServiceOne(ActivityOrderService.class).count(
                    new QueryWrapper().eq("orderType", 1).between("created", DateUtils.todayStart(-1).getTime(), DateUtils.todayEnd(-1).getTime())
            );
            return Lists.newArrayList(
                    DashboardItem.builder().label("今日订单数").value(totalCount).type(dashboardType()).build(),
                    DashboardItem.builder().label("昨日订单数").value(waitReviewCount).type(dashboardType()).build()
            );
        }

        @Override
        public String dashboardType() {
            return "order";
        }
    }

    @Service
    public class UserDashboardService implements IPlatformDashboardService {
        @Override
        public List<DashboardItem> dashboardData() {
            long totalCount = dispatchContext.getServiceOne(UserService.class).count(new QueryWrapper());
            long waitReviewCount = dispatchContext.getServiceOne(UserService.class).count(
                    new QueryWrapper().between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime())
            );
            return Lists.newArrayList(
                    DashboardItem.builder().label("会员总数").value(totalCount).type(dashboardType()).build(),
                    DashboardItem.builder().label("今日注册").value(waitReviewCount).type(dashboardType()).build()
            );
        }

        @Override
        public String dashboardType() {
            return "user";
        }
    }

    @Service
    public class ActivityDashboardService implements IPlatformDashboardService {
        @Override
        public List<DashboardItem> dashboardData() {
            long totalCount = dispatchContext.getServiceOne(ActivityService.class).count(new QueryWrapper()
                    .between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime()));
            long waitReviewCount = dispatchContext.getServiceOne(ActivityService.class).count(
                    new QueryWrapper().between("created", DateUtils.todayStart(-1).getTime(), DateUtils.todayEnd(-1).getTime())
            );
            return Lists.newArrayList(
                    DashboardItem.builder().label("今日新增活动").value(totalCount).type(dashboardType()).build(),
                    DashboardItem.builder().label("昨日新增活动").value(waitReviewCount).type(dashboardType()).build()
            );
        }

        @Override
        public String dashboardType() {
            return "activity";
        }
    }

    @Service
    public class ActivityGroupDashboardService implements IPlatformDashboardService {
        @Override
        public List<DashboardItem> dashboardData() {
            long totalCount = dispatchContext.getServiceOne(ActivityGroupOrderService.class).count(new QueryWrapper()
                    .eq("status", 2).between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime()));
            long waitReviewCount = dispatchContext.getServiceOne(ActivityGroupOrderService.class).count(
                    new QueryWrapper().eq("status", 2).between("created", DateUtils.todayStart(-1).getTime(), DateUtils.todayEnd(-1).getTime())
            );
            return Lists.newArrayList(
                    DashboardItem.builder().label("今日成团").value(totalCount).type(dashboardType()).build(),
                    DashboardItem.builder().label("昨日成团").value(waitReviewCount).type(dashboardType()).build()
            );
        }

        @Override
        public String dashboardType() {
            return "group";
        }
    }

    @Service
    public class ActivitySpikeDashboardService implements IPlatformDashboardService {
        @Override
        public List<DashboardItem> dashboardData() {
            long totalCount = dispatchContext.getServiceOne(ActivityOrderService.class).count(new QueryWrapper()
                    .eq("activityType", ActivityType.SPIKE).eq("orderType", 1).between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime()));
            long waitReviewCount = dispatchContext.getServiceOne(ActivityOrderService.class).count(
                    new QueryWrapper()
                            .eq("activityType", ActivityType.SPIKE).eq("orderType", 1).between("created", DateUtils.todayStart(-1).getTime(), DateUtils.todayEnd(-1).getTime())
            );
            return Lists.newArrayList(
                    DashboardItem.builder().label("今日秒杀下单数").value(totalCount).type(dashboardType()).build(),
                    DashboardItem.builder().label("昨日秒杀下单数").value(waitReviewCount).type(dashboardType()).build()
            );
        }

        @Override
        public String dashboardType() {
            return "spike";
        }
    }

    @Service
    public class ActivityLotteryDashboardService implements IPlatformDashboardService {
        @Override
        public List<DashboardItem> dashboardData() {
            long totalCount = dispatchContext.getServiceOne(ActivityLotteryOrderService.class).count(new QueryWrapper()
                    .eq("lotteryState", 1).between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime()));
            long waitReviewCount = dispatchContext.getServiceOne(ActivityLotteryOrderService.class).count(
                    new QueryWrapper()
                            .eq("lotteryState", 1).between("created", DateUtils.todayStart(-1).getTime(), DateUtils.todayEnd(-1).getTime())
            );
            return Lists.newArrayList(
                    DashboardItem.builder().label("今日中奖人数").value(totalCount).type(dashboardType()).build(),
                    DashboardItem.builder().label("昨日中奖人数").value(waitReviewCount).type(dashboardType()).build()
            );
        }

        @Override
        public String dashboardType() {
            return "lottery";
        }
    }

    @Service
    public class ActivityRechargeDashboardService implements IPlatformDashboardService {
        @Override
        public List<DashboardItem> dashboardData() {
            EntityManager em = dispatchContext.getServiceOne(RechargeService.class).getFactory().createEntityManager();
            try {
                return Lists.newArrayList(
                        DashboardItem.builder().label("今日用户充值金额").value(sumTotalMoney(em, TokenType.ROLE_USER, DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime())).type(dashboardType()).build(),
                        DashboardItem.builder().label("昨日用户充值金额").value(sumTotalMoney(em, TokenType.ROLE_USER, DateUtils.todayStart(-1).getTime(), DateUtils.todayEnd(-1).getTime())).type(dashboardType()).build()
                );
            } finally {
                dispatchContext.getServiceOne(RechargeService.class).closeEntityManger(em);
            }
        }

        @Override
        public String dashboardType() {
            return "recharge_user";
        }
    }

    @Service
    public class ActivityRechargeShopDashboardService implements IPlatformDashboardService {
        @Override
        public List<DashboardItem> dashboardData() {
            EntityManager em = dispatchContext.getServiceOne(RechargeService.class).getFactory().createEntityManager();
            try {
                return Lists.newArrayList(
                        DashboardItem.builder().label("今日商家充值金额").value(sumTotalMoney(em, AppConst.FID_TYPE_SHOP, DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime())).type(dashboardType()).build(),
                        DashboardItem.builder().label("昨日商家充值金额").value(sumTotalMoney(em, AppConst.FID_TYPE_SHOP, DateUtils.todayStart(-1).getTime(), DateUtils.todayEnd(-1).getTime())).type(dashboardType()).build()
                );
            } finally {
                dispatchContext.getServiceOne(RechargeService.class).closeEntityManger(em);
            }
        }

        @Override
        public String dashboardType() {
            return "recharge_shop";
        }
    }


    @Service
    public class FinanceUserWithdrawDashboardService implements IPlatformDashboardService {
        @Override
        public List<DashboardItem> dashboardData() {
            long totalCount = dispatchContext.getServiceOne(WithdrawService.class).count(new QueryWrapper()
                    .eq("status", WithdrawStatus.WAIT_REVIEW).eq("fidType", TokenType.ROLE_USER).between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime()));
            long waitReviewCount = dispatchContext.getServiceOne(WithdrawService.class).count(
                    new QueryWrapper()
                            .eq("fidType", TokenType.ROLE_USER).between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime())
            );
            return Lists.newArrayList(
                    DashboardItem.builder().label("用户提现待审核").value(totalCount).type(dashboardType()).build(),
                    DashboardItem.builder().label("今日提现总数").value(waitReviewCount).type(dashboardType()).build()
            );
        }
        @Override
        public String dashboardType() {
            return "withdraw_user";
        }
    }
    @Service
    public class FinanceShopWithdrawDashboardService implements IPlatformDashboardService {
        @Override
        public List<DashboardItem> dashboardData() {
            long totalCount = dispatchContext.getServiceOne(WithdrawService.class).count(new QueryWrapper()
                    .eq("status", WithdrawStatus.WAIT_REVIEW).eq("fidType", AppConst.FID_TYPE_SHOP).between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime()));
            long waitReviewCount = dispatchContext.getServiceOne(WithdrawService.class).count(
                    new QueryWrapper()
                            .eq("fidType", AppConst.FID_TYPE_SHOP).between("created", DateUtils.todayStart(0).getTime(), DateUtils.todayEnd(0).getTime())
            );
            return Lists.newArrayList(
                    DashboardItem.builder().label("商家提现待审核").value(totalCount).type(dashboardType()).build(),
                    DashboardItem.builder().label("今日提现总数").value(waitReviewCount).type(dashboardType()).build()
            );
        }
        @Override
        public String dashboardType() {
            return "withdraw_shop";
        }
    }

}
